package com.example.mysql.学习笔记.高级.数据库的优化之索引.数据库调优的其他策略;

public class 大表优化 {
}
/**
 * 4.大表优化
 * 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降，一些常见的优化措施如下:
 * 4.1限定查询的范围
 * 禁止不带任何限制数据范围条件的查询语句。
 * 比如:我们当用户在查询订单历史的时候，我们可以控制在一个月的范围内;
 * 4.2读/写分离
 * 经典的数据库拆分方案，主库负责写，从库负责读。
 * ●一主一从模式:  Java程序->Mycat(中间件)->读从表  写主表
 *                  MySQL主从复制同步主从表信息
 * ●双主双从模式:  防止主表宕机弄个两主相互复制防止其中一个宕机
 *
 * 4.3垂直拆分
 *    当数据量级达到千万级以上时，有时候我们需要把一个数据库切成多份,
 *    放到不同的数据库服务器上,减少对单一数据库服务器的访问压力。
 * ●如果数据库中的数据表过多,可以采用垂直分库的方式，将关联的数据表部署在同一个数据库上。
 * ●如果数据表中的列过多,可以采用垂直分表的方式，将一张数据表分拆成多张数据表,
 *   把经常一起使用的列放到同一张表里。
 *
 * 垂直拆分的优点: 可以使得列数据变小， 在查询时减少读取的Block数，减少I/0次数。
 *              此外，垂直分区可以简化表的结构，易于维护。
 * 垂直拆分的缺点: 主键会出现冗余，需要管理冗余列，并会引起JOIN操作。
 *              此外,垂直拆分会让事务变得更加复杂。
 *
 * 4.4水平拆分
 * ●尽量控制单表数据量的大小，建议控制在1000万以内。
 *  1000万并不是MySQL数据库的限制， 过大会造成修改表结构、备份、恢复都会有很大的问题。
 *  此时可以用历史数据归档(应用于日志数据) ，水平分表(应用于业务数据)等手段来控制数据量大小。
 * ● 这里我们主要考虑业务数据的水平分表策略。
 *   将大的数据表按照某个属性维度分拆成不同的小表，每张小表保持相同的表结构。
 *   比如你可以按照年份来划分,把不同年份的数据放到不同的数据表中。
 *   2017年、 2018 年和2019年的数据就可以分别放到三张数据表中。
 * ● 水平分表仅是解决了单一表数据过大的问题，但由于表的数据还是在同一台机器上,
 *   其实对于提升MySQL并发能力没有什么意义，所以水平拆分最好分库,从而达到分布式的目的。
 *
 * 水平拆分能够支持非常大的数据量存储，应用端改造也少,但分片事务难以解决，跨节点Join性能较差，逻辑复杂。
 * 《Java工程师修炼之道》 的作者推荐尽量不要对数据进行分片, 因为拆分会带来逻辑、部署、运维的各种复杂度，
 * 一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。
 * 如果实在要分片，尽量选择客户端分片架构，这样可以减少一次和中间件的网络I/0。
 *
 * 下面补充一下数据库分片的两种常见方案:
 * ●客户端代理: 分片逻辑在应用端，封装在jar包中,通过修改或者封装JDBC层来实现。
 *   当当网的Sharding-DBC、阿里的 TDDL 是两种比较常用的实现。
 * ●中间件代理: 在应用和数据中间加了一个代理层。分片逻辑统-维护在中间件服务中。
 *   我们现在谈的Mycat 、360的Atlas、 网易的DDB等等都是这种架构的实现。
 *
 */

/**
 *5.其它调优策略
 * 5.1服务器语句超时处理
 * 在MySQL 8.0中可以设置服务器语句超时的限制，单位可以达到亳秒级别。
 * 当中断的执行语句超过设置的毫秒数后，服务器将终止查询影响不大的事务或连接,然后将错误报给客户端。
 * 设置服务器语句超时的限制，可以通过设置系统变量MAX_EXECUTION_TIME来实现。
 * 默认情况下，MAX_EXECUTION_TIME的值为0,代表没有时间限制。
 * SET MAX_EXECUTION_TIME=2000;//#指定该会话中SELECT语句的超时时间|
 *
 * 5.2创建全局通用表空间
 * MySQL 8.0使用 CREATE TABLESPACE 语句来创建一个全局通用表空间。
 * 全局表空间可以被所有的数据库的表共享，而且相比于独享表空间，使用手动创建共享表空间可以节约元数据方面的内存。
 * 可以在创建表的时候，指定属于哪个表空间，也可以对已有表进行表空间修改等。
 *
 * 5.3 MySQL 8.0新特性: 隐藏索引对调优的帮助
 * 不可见索引的特性对于性能调试非常有用。在MySQL 8.0中，索引可以被“隐藏"和“显示”。
 * 当--个索引被隐藏时，它不会被查询优化器所使用。
 * 也就是说，管理员可以隐藏一个索引，然后观察对数据库的影响。
 * 如果数据库性能有所下降，就说明这个索引是有用的，于是将其“恢复显示”即可;
 * 如果数据库性能看不出变化，就说明这个索引是多余的，可以删掉了。
 * 需要注意的是当索引被隐藏时，它的内容仍然是和正常索引-样实时更新的。
 * 如果一个索引需要长期被隐藏，那么可以将其删除，因为索引的存在会影响插入、更新和删除的性能。
 *
 * 数据表中的主键不能被设置为invisible(看不见的  隐藏索引)。
 *
 */
